//
//  ECSViewController.m
//  ECS DevelopKit
//
//  Created by LittoCats on 8/17/14.
//  Copyright (c) 2014 Littocats. All rights reserved.
//

#import "ECSViewController.h"
#import "ECSUtilities.h"
#import "ECSUIBuilder.h"

#import "ECSUIDelegate+UIBarButtonItem.h"

#import <objc/message.h>

@interface ECSViewController ()

@property (nonatomic, strong) ECSScriptContext *ecsContext;

@property (nonatomic, strong) NSMutableDictionary *parameter;

@property (nonatomic, strong) NSDictionary *attribute;

@property (nonatomic, strong) NSString *identifier;

@end

@implementation ECSViewController

- (id)initWithIdentifier:(NSString *)identifier parameter:(NSDictionary *)parameter attribute:(NSDictionary *)attribute
{
    self = [super init];
    if (self) {
        self.parameter = [NSMutableDictionary dictionaryWithDictionary:parameter];
        
        //解析 viewControll identifier 及 script 路径
        NSArray *ids = [identifier componentsSeparatedByString:@">>"];
        NSString *absoluteIdentifier = [ids firstObject];
        if ((!absoluteIdentifier || [absoluteIdentifier isEmpty]))
            @throw [[NSException alloc] initWithName:@"[ECSViewController init error]" reason:@"identifier 和 script 为空" userInfo:nil];
        
        NSString *script = attribute[@"script"];
        if (!script || [script isEmpty]) script = absoluteIdentifier;
        
        NSString *layout = attribute[@"layout"];
        if (!layout || [layout isEmpty]) layout = script;
        
        NSString *path = attribute[@"path"];
        if (!path || [path isEmpty]) path = [[NSHomeDirectory() stringByAppendingPathComponent:[@"Library" stringByAppendingPathComponent:ECSProjectResourceRootPath]] stringByAppendingPathComponent:absoluteIdentifier];
        self.attribute = [NSDictionary dictionaryWithObjectsAndKeys:script,@"script",
                          layout,@"layout",
                          path,@"path",
                          nil];
        
        self.identifier = [ids componentsJoinedByString:@""];
        
        //初始化 scriptContext
        self.ecsContext = [ECSScriptContext context];
        // context 中记录当前的路径
        ECS_WrapObjectAttribute(_ecsContext, path, ECSContextPathKey);
        NSString *scriptConst = [[NSString alloc] initWithFormat:@"var %@ = '%@';_env.path = '%@';",ECSViewControllerIdkeyInContext,self._id,_attribute[@"path"]];
        NSString *scriptSrc = [self sourceStringInRelativePath:_attribute[@"script"] type:@"js"];
        script = [scriptConst stringByAppendingString:scriptSrc ? scriptSrc : @""];
        [_ecsContext evaluateScript:script];
    }
    return self;
}

- (void)loadView
{
    NSData *layoutSrc = [self sourceDataInRelativePath:[_attribute[@"layout"] stringByAppendingPathExtension:@"json"]];
    NSDictionary *layout = layoutSrc && ![layoutSrc isEmpty] ? [NSJSONSerialization JSONObjectWithData:layoutSrc options:0 error:nil] : @{};
    self.view = [ECSUIBuilder viewWithAttributes:layout context:_ecsContext];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self.parameter[ECSViewControllerLiftCircle_viewDidLoad] evaluateWithArguments:nil];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    [self.parameter[ECSViewControllerLiftCircle_viewWillAppear] evaluateWithArguments:nil];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    
    [self.parameter[ECSViewControllerLiftCircle_viewDidAppear] evaluateWithArguments:nil];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    [self.parameter[ECSViewControllerLiftCircle_viewWillDisappear] evaluateWithArguments:nil];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    
    [self.parameter[ECSViewControllerLiftCircle_viewDidDisappear] evaluateWithArguments:nil];
}

#pragma mark
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark- viewcontroller 管理
- (void)setIdentifier:(NSString *)identifier
{
    [[ECSViewController viewControllerTable] removeObjectForKey:_identifier];
    [[ECSViewController viewControllerTable] setObject:self forKey:identifier];
    
    _identifier = identifier;
}
+ (ECSViewController *)viewControllerWithIdentifier:(NSString *)identifier
{
    return [identifier hasPrefix:@"ECSViewController"] ? [NSObject findObjectById:identifier] : [[self viewControllerTable] objectForKey:[identifier stringByReplacingOccurrencesOfString:@">>" withString:@""]];
}

+ (NSMapTable *)viewControllerTable
{
    static NSMapTable *table = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        table = [NSMapTable strongToWeakObjectsMapTable];
    });
    return table;
}

@end

@implementation ECSViewController (ECSParameter)

- (id)parameterForKey:(id<NSCopying>)key
{
    return [self.parameter objectForKey:key];
}
- (void)setParameter:(id)parameter forKey:(id<NSCopying>)key
{
    [self.parameter setObject:parameter forKey:key];
}

@end

@implementation ECSViewController (ECSNavigationBar)

- (void)updateNavigation:(NSDictionary *)items animated:(BOOL)animated
{
    for (NSString *type in items) {
        SEL selector = NSSelectorFromString([[NSString alloc] initWithFormat:@"setNavigationBar%@Item:animated:",[type capitalizedString]]);
        objc_msgSend(self, selector, items[type], animated);
    }
}

- (void)setNavigationBarLeftItem:(NSDictionary *)attribute animated:(BOOL)animated
{
    if (!attribute || [attribute isEmpty]) self.navigationItem.leftBarButtonItem = nil;
    UIBarButtonItem *item = [self navigationBarButtonItemWithAttribute:attribute];
    item.action = @selector(leftItemClicked:);
    self.navigationItem.leftBarButtonItem = item;
}

- (void)setNavigationBarTitleItem:(id)attribute animated:(BOOL)animated
{
    if ([attribute isKindOfClass:NSString.class]) self.title = attribute;
    else{
        UIBarButtonItem *item = [self navigationBarButtonItemWithAttribute:attribute];
        item.action = @selector(backButtonItemClicked:);
        self.navigationItem.backBarButtonItem = item;
    }
}

- (void)setNavigationBarBackItem:(NSDictionary *)attribute animated:(BOOL)animated
{
    if (!attribute || [attribute isEmpty]) [self.navigationItem setHidesBackButton:YES animated:animated];
    //自定义返回键
}

- (void)setNavigationBarRightItem:(id)attributes animated:(BOOL)animated
{
    if (!attributes || [attributes isEmpty]) self.navigationItem.rightBarButtonItems = @[];

}

- (UIBarButtonItem *)navigationBarButtonItemWithAttribute:(NSDictionary *)attribute
{
    NSString *title = attribute[@"title"];
    UIImage *image = [UIImage imageWithScript:attribute[@"image"]];
    
    UIBarButtonItem *item;
    if (image) item = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:[ECSUIDelegate defaultInstance] action:NULL];
    else item = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStylePlain target:[ECSUIDelegate defaultInstance] action:NULL];
    ECS_WrapObjectAttribute(item, attribute, ECSUINavigationBarItemAttributesKey);
    return item;
}

@end

@implementation ECSViewController (ECSNavigationController)

+ (void)pushViewController:(ECSViewController *)nvc fromViewController:(ECSViewController *)ovc animated:(BOOL)animated
{
    if (!ovc || [ovc isEmpty]) {
        [UIApplication sharedApplication].keyWindow.rootViewController = [[UINavigationController alloc] initWithRootViewController:nvc];
        return;
    }
    
    UINavigationController *navc = ovc.navigationController;
    if (!navc) {
        [ovc presentViewController:nvc animated:animated completion:nil];
        return;
    }
    
    if (ovc != navc.topViewController) {
        [navc popToViewController:ovc animated:NO];
    }
    [navc pushViewController:nvc animated:animated];
}

+ (void)popViewController:(ECSViewController *)vc animated:(BOOL)animated
{
    UINavigationController *navc = vc.navigationController;
    if (!navc) {
        [vc dismissViewControllerAnimated:animated completion:nil];
        return;
    }
    
    [navc popToViewController:vc animated:NO];
    [navc popViewControllerAnimated:animated];
}
@end

@implementation ECSViewController (ECSResourceManager)

- (NSData *)sourceDataInRelativePath:(NSString *)relativePath
{
    return [[NSData alloc] initWithContentsOfFile:[[_attribute[@"path"] stringByAppendingPathComponent:relativePath] stringByResolvingSymlinksInPath]];
}

- (NSString *)sourceStringInRelativePath:(NSString *)relativePath type:(NSString *)type
{
    return [[NSString alloc] initWithData:[self sourceDataInRelativePath:[relativePath stringByAppendingPathExtension:type]] encoding:NSUTF8StringEncoding];
}

- (id)sourceInRelativePath:(NSString *)relativePath type:(NSString *)type
{
    NSData *data = [self sourceDataInRelativePath:[relativePath stringByAppendingPathExtension:type]];
    return data;
}
@end